<script setup lang="ts">

import {onMounted, ref} from "vue";
import {basicSetup, EditorView} from "codemirror";
import {EditorViewConfig} from "@codemirror/view";
import {EditorState} from "@codemirror/state";
import {ayuLight} from "thememirror";
import {java} from "@codemirror/lang-java";

const props = defineProps({
  doc: {
    type: String,
    required: true
  },
});
//========================== 生命周期 ==========================
const content = ref("");
const editorView = ref<EditorView>();
onMounted(() => {
  //创建编辑器
  const editor = new EditorView({
    state: EditorState.create({
      doc: props.doc,
      extensions: [
        basicSetup,
        java(),
        ayuLight,
        //视图更新时会回调
        EditorView.updateListener.of((viewUpdate) => {
          let contentUpdate = viewUpdate.state.doc.toString();
          if (content.value != contentUpdate) {
            content.value = viewUpdate.state.doc.toString();
            contentChange(editor.state.doc.toString());
          }
        })
      ],
    }),
    parent: document.getElementById("content")
  } as EditorViewConfig);
  editorView.value = editor;
})
//========================== 回调事件 ==========================
const emits = defineEmits(["contentChange"])

function contentChange(contentChange: string) {
  emits("contentChange", contentChange);
}

//========================== 暴露方法 ==========================
function setContent(str: string) {
  //转字符串否则报错
  content.value = str+"";
  editorView.value.dispatch({
    changes: {from: 0, to: editorView.value.state.doc.length, insert: content.value}
  })
}

function getContent(): string {
  return content.value;
}

defineExpose({setContent, getContent})
</script>

<template>
  <div>
    <div id="content"/>
  </div>
</template>

<style scoped lang="scss">

</style>